﻿using System;
using System.Collections.Generic;

namespace Streaming_Service.Test {
    using System.IO;
    using System.Text;
    using NUnit.Framework;
    using Enum;
    using FileTransfer;
    using Media;
    using SQL_Ting;
    using User;

    [TestFixture]
    public class TestMovie {
        private Streaming_Service.RentIt11 client;

        [SetUp]
        public void SetUp() {
            client = new RentIt11();
        }

        [Test]
        public void GetMovieData() {
            Assert.That(client != null);
            var movies = client.ListMovies();
            Assert.That(movies != null && movies.Count > 0 && movies.Count == client.MovieCount());
            
            var movie = movies[DBFunc.Rand(0, movies.Count - 1)];
            Assert.That(movie != null);

            var movieInfo = client.MovieInfo(0);
            Assert.That(movieInfo == null);
                
            movieInfo = client.MovieInfo(movie.Id);
            Assert.That(movie.Id == movieInfo.Id);
            Assert.That(movie.LengthFormatted == movieInfo.LengthFormatted);
            Assert.That(movie.MovieDownloadUrl == movieInfo.MovieDownloadUrl);
            Assert.That(movie.MovieDownloadUrlHD == movieInfo.MovieDownloadUrlHD);

            Assert.That(client.MovieExists(movieInfo.Title, movieInfo.Year));
            Assert.That(!client.MovieExists(null, 2000));
            Assert.That(!client.MovieExists(movieInfo.Title, 0));

            Assert.That(client.MovieExistsImdb(movieInfo.ImdbId));
            Assert.That(!client.MovieExistsImdb("xthisisnotimdbx"));

            Assert.That(client.GetSdPrice(movieInfo) == client.GetSdPriceByMovieId(movie.Id));
            Assert.That(client.GetHdPrice(movie) == client.GetHdPriceByMovieId(movieInfo.Id));

            var sh = DBHandler.GetHandler();
            sh.Connect();
            Assert.That(MovieQueries.LatestId(sh) > 0);
            sh.Close();

            var languages = client.ListMovieLanguages();
            Assert.That(languages.Count > 0);
        }

        [Test]
        public void ManageMovie() {
            var admin = TestUser.GetAdminSession();

            var movieEntry = new MovieEntry();
            Assert.That(client.InsertMovie(new UserSession(), movieEntry) == -1);
            movieEntry.Summary = DBFunc.RandStr(30);
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.Title = "The Shawshank Redemption";
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.Year = 1994;
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.Length = 142;
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.Language = "English";
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.ParentalGuidance = ParentalGuidance.R;
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.HighDefinition = XBool.False;
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.ReleaseDate = new DateTime(1995, 4, 28);
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.ImdbId = "tt0111161";
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.Year = 1996;
            Assert.That(client.InsertMovie(admin, movieEntry) == -1);
            movieEntry.ImdbId = "tt01111619";

            var theId = client.InsertMovie(admin, movieEntry);
            Assert.That(theId > 0);

            Assert.That(!client.EditMovie(new UserSession(), theId, movieEntry));
            Assert.That(!client.EditMovie(admin, theId, new MovieEntry()));
            Assert.That(client.EditMovie(admin, theId, movieEntry));
            movieEntry.Year = 1992;
            Assert.That(client.EditMovie(admin, theId, movieEntry));

            Assert.That(!client.DeleteMovie(new UserSession(), theId));
            Assert.That(!client.DeleteMovie(admin, -1));
            Assert.That(client.DeleteMovie(admin, theId));

            movieEntry.MovieDownloadUrl = "Test";
            movieEntry.MovieDownloadUrlHD = "Test";
            movieEntry.ThumbUrl = "Test";
            movieEntry.LengthFormatted = "Test";
        }

        [Test]
        public void Searching() {
            var user = TestUser.GetAdminSession();

            var searches = client.ListAllSearches(-1, 1);
            Assert.That(searches.Count <= 1);

            searches = client.ListAllSearches(-1, 100);
            Assert.That(searches.Count >= 0 && searches.Count <= 100);

            var ms = new MovieSearchEntry();
            ms.AllMustMatch = false;

            var results = new List<List<MovieEntry>>();
            results.Add(client.SearchMovies(ms));
            Assert.That(results[0].Count == 0);

            ms.MovieEntry.Year = 2000;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[1].Count > 0);

            ms.YearDifference = 5;
            ms.YearDifferenceDirection = DifferenceDirection.Both;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[2].Count > 0);

            ms.MovieEntry.Length = 120;
            ms.LengthDifference = 60;
            ms.LengthDifferenceDirection = DifferenceDirection.Higher;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[3].Count > 0);

            ms.MovieEntry.ParentalGuidance = ParentalGuidance.G;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[4].Count > 0);

            ms.MovieEntry.Title = "he";
            ms.TitleIsPartial = true;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[5].Count > 0);

            ms.TitleIsPartial = false;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[6].Count > 0);

            ms.TitleIsPartial = true;
            ms.UserID = user.UserId;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[7].Count > 0);

            ms.DoNotSaveToSearchHistory = true;
            ms.MovieEntry.ReleaseDate = new DateTime(1995, 4, 1);
            ms.ReleaseDateSpecification = DateSpecification.Year;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[8].Count > 0);

            ms.ReleaseDateSpecification = DateSpecification.YearMonth;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[9].Count > 0);

            ms.ReleaseDateSpecification = DateSpecification.Complete;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[10].Count > 0);

            ms.AllMustMatch = true;
            results.Add(client.SearchMovies(ms));
            Assert.That(results[11].Count == 0);
        }

        [Test]
        public void MediaUpload() {
            var admin = TestUser.GetAdminSession();

            var movie = RandomMovie();
            Assert.That(movie.Id > 0 && !string.IsNullOrEmpty(movie.ImdbId));
            Assert.That(client.AllowedMovieFileExtensions().Count > 0);
            Assert.That(client.AllowedThumbFileExtensions().Count > 0);

            var tmpPath = "testimdbthumb_" + Environment.TickCount + "_" + movie.ImdbId + ".jpg";

            var thumbUrl = movie.ThumbUrl;
            if (!thumbUrl.Contains("://")) thumbUrl = "http://localhost:2116/" + thumbUrl;
            this.DownloadFile(thumbUrl, tmpPath);
            MediaFunc.GetContentType(tmpPath);
            MediaFunc.GetContentType(tmpPath + "testfiledoesnotexist");

            var fi = new FileInfo(tmpPath);
            var uInfo = new UploadFileInfo { Admin = admin, MovieId = movie.Id, Filename = fi.Name, Size = fi.Length };
            Assert.That(FileTransferHelper.VerifyThumbFileExtension(uInfo));

            using( var fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) {
                uInfo.FileByteStream = fs;
                Assert.That(client.UploadMovieThumb(uInfo).Success);
                uInfo.Filename = "";
                Assert.That(!client.UploadMovieThumb(uInfo).Success);
                uInfo.Admin = new UserSession();
                Assert.That(!client.UploadMovieThumb(uInfo).Success);
            }

            File.Delete(tmpPath);

            var movieData = Crawler.ImdbCrawler.GetPage(movie.MovieDownloadUrl);
            Assert.That(!string.IsNullOrEmpty(movieData), "SD Download");
            movieData = Crawler.ImdbCrawler.GetPage(movie.MovieDownloadUrlHD);
            Assert.That(!string.IsNullOrEmpty(movieData), "HD Download");

            uInfo.Filename += ".mp4";
            Assert.That(FileTransferHelper.VerifyMovieFileExtension(uInfo));

            Assert.That(!FileTransferHelper.ProperUploadFileInfo(null));
            uInfo = new UploadFileInfo();
            Assert.That(!FileTransferHelper.ProperUploadFileInfo(uInfo));
            uInfo.Filename = "test.jpg";
            Assert.That(!FileTransferHelper.ProperUploadFileInfo(uInfo));
            uInfo.Size = 10;
            Assert.That(!FileTransferHelper.ProperUploadFileInfo(uInfo));
        }

        [Test]
        public void ImdbCrawling() {
            var imdbIds = new []
                {
                    "tt1506999" /* Haywire */,
                    "tt1232829" /* 21 Jump Street */,
                    "tt1210166" /* Moneyball */,
                    "tt1058017" /* The Invention of Lying */,
                    "tt0995039" /* GhostTown */
                }
            ;

            var theId = imdbIds[DBFunc.Rand(0, imdbIds.Length - 1)];

            var imdb = client.GetImdbMovie(theId);

            Assert.That(imdb.ImdbId == theId);
            Assert.That(imdb.Genre.Count > 0);
            Assert.That(!string.IsNullOrEmpty(imdb.ImdbHtml));
            Assert.That(!string.IsNullOrEmpty(imdb.Language));
            Assert.That(imdb.Length > 0);
            Assert.That(!string.IsNullOrEmpty(imdb.Summary));
            Assert.That(!string.IsNullOrEmpty(imdb.Title));
            Assert.That(imdb.Year > 2000);
            Assert.That(imdb.ParentalGuidance != ParentalGuidance.Ignore);
            Assert.That(imdb.ReleaseDate.Year > 1990);
            Assert.That(imdb.ThumbData.Length > 0);
        }

        public static MovieEntry RandomMovie() {
            var client = new RentIt11();
            var movies = client.ListMovies();
            return movies[DBFunc.Rand(0, movies.Count - 1)];
        }

        private void DownloadFile(string url, string path) {
            Console.WriteLine("Thumb url:" + url);
            var data = Crawler.ImdbCrawler.GetPage(url);

            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write)) {
                var bytes = Encoding.Default.GetBytes(data);
                fs.Write(bytes, 0, bytes.Length);
            }
        }
    }
}